/**
 * 
 */
package pl.kaczanowscy.tomek.ipdl;

import java.util.HashMap;
import java.util.Map;

/**
 * Implementation of {@link GameResult} for two players game.
 * 
 * @author Tomek Kaczanowski
 * 
 */
public final class TwoPlayersGameResult implements GameResult {

	private static final Integer BEGIN_PAYOFF = 0;
	private final Map<Strategy, Integer> payoff;

	/**
	 * Remembers strategies that play the game.
	 * 
	 * @param strategyA
	 *            first strategy
	 * @param strategyB
	 *            second strategy
	 */
	public TwoPlayersGameResult(Strategy strategyA, Strategy strategyB) {
		payoff = new HashMap<Strategy, Integer>(2);
		payoff.put(strategyA, BEGIN_PAYOFF);
		payoff.put(strategyB, BEGIN_PAYOFF);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * pl.kaczanowscy.tomek.ipdl.GameResult#getPayoff(pl.kaczanowscy.tomek.ipdl
	 * .Strategy)
	 */
	@Override
	public int getPayoff(Strategy strategy) {
		if (!payoff.containsKey(strategy)) {
			throwNoSuchStrategyException(strategy);
		}
		return payoff.get(strategy);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * pl.kaczanowscy.tomek.ipdl.GameResult#addPayoff(pl.kaczanowscy.tomek.ipdl
	 * .Strategy, int)
	 */
	@Override
	public void addPayoff(Strategy strategy, int payoffToAdd) {
		if (!payoff.containsKey(strategy)) {
			throwNoSuchStrategyException(strategy);
		}
		int currentPayoff = payoff.get(strategy);
		payoff.put(strategy, currentPayoff + payoffToAdd);
	}

	@Override
	public String toString() {
		StringBuilder result = new StringBuilder();
		result.append("result: ");
		for (Map.Entry<Strategy, Integer> entry : payoff.entrySet()) {
			result.append(entry.getKey());
			result.append(": ");
			result.append(entry.getValue());
			result.append(", ");
		}
		return result.toString();
	}

	private void throwNoSuchStrategyException(Strategy strategy) {
		StringBuilder errMsg = new StringBuilder("Strategy [" + strategy
				+ "] is not a part of this game result. Available strategies: ");
		for (Strategy tempStrategy : payoff.keySet()) {
			errMsg.append(tempStrategy);
			errMsg.append(",");
		}
		throw new IllegalArgumentException(errMsg.toString());
	}
}
